package com.ruoyi.web.controller.system;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.EmptyUtils;
import com.ruoyi.common.utils.IdWorker;
import com.ruoyi.system.domain.AppMenu;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;

/**
 * 用户信息
 * 
 * @author ruoyi
 */
@Controller
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
    private String prefix = "system/user";

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysPostService postService;

    @Autowired
    private SysPasswordService passwordService;

    @RequiresPermissions("system:user:view")
    @GetMapping()
    public String user()
    {
        return prefix + "/user";
    }

    @GetMapping("/lockUser/{addressId}")
    public String lockUser(@PathVariable("addressId") Long addressId, ModelMap mmap)
    {
        mmap.put("addressId",addressId);
        return prefix + "/lockUser";
    }

    @RequiresPermissions("system:user:view")
    @GetMapping("/choseMenu/{roleId}")
    public String choseMenu(@PathVariable("roleId") Long roleId, ModelMap mmap)
    {
        mmap.put("roleId",roleId);
        return prefix + "/choseMenu";
    }

    @RequiresPermissions("system:user:view")
    @GetMapping("/updateMenu/{roleId}/{userId}")
    public String updateMenu(@PathVariable("roleId") Long roleId,@PathVariable("userId") Long userId, ModelMap mmap)
    {
        mmap.put("roleId",roleId);
        mmap.put("userId",userId);
        mmap.put("loginName",userService.selectUserById(userId).getLoginName());
        return prefix + "/updateMenu";
    }

    @RequiresPermissions("system:user:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }

    @PostMapping("/listAssignUser")
    @ResponseBody
    public TableDataInfo listAssignUser(SysUser user)
    {
        startPage();
        user.setStatus("0");
        List<SysUser> list = userService.selectAssignUserList(user);
        return getDataTable(list);
    }

    @PostMapping("/riseSuper")
    @ResponseBody
    public AjaxResult riseSuper(Long id)
    {
        SysUser sysUser = userService.selectUserById(id);
        sysUser.setIsSuper("1");
        int num = userService.updateUserSuper(sysUser);
        return toAjax(num);
    }

    @PostMapping("/downSuper")
    @ResponseBody
    public AjaxResult downSuper(Long id)
    {
        SysUser sysUser = userService.selectUserById(id);
        sysUser.setIsSuper("0");
        int num = userService.updateUserSuper(sysUser);
        return toAjax(num);
    }

    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:user:export")
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SysUser user)
    {
        List<SysUser> list = userService.selectUserList(user);
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.exportExcel(list, "用户数据");
    }

    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @RequiresPermissions("system:user:import")
    @PostMapping("/importData")
    @ResponseBody
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        List<SysUser> userList = util.importExcel(file.getInputStream());
        String operName = ShiroUtils.getSysUser().getLoginName();
        String message = userService.importUser(userList, updateSupport, operName);
        return AjaxResult.success(message);
    }

    @RequiresPermissions("system:user:view")
    @GetMapping("/importTemplate")
    @ResponseBody
    public AjaxResult importTemplate()
    {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.importTemplateExcel("用户数据");
    }

    /**
     * 新增用户
     */
    @GetMapping("/add")
    public String add(ModelMap mmap)
    {
        mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        mmap.put("posts", postService.selectPostAll());
        return prefix + "/add";
    }

    /**
     * 新增保存用户
     */
    @Transactional
    @RequiresPermissions("system:user:add")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(@Validated SysUser user)
    {
        if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName())))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
        user.setCreateBy(ShiroUtils.getLoginName());
        /*//先添加角色信息
        String[] functionMenus = user.getFunctionMenu().split(",");
        Long[] menuRole =(Long[]) ConvertUtils.convert(functionMenus,Long.class);
        SysRole sysRole = new SysRole();
        Long roleId = roleService.selectMaxRoleId()+1;
        sysRole.setRoleId(roleId);
        sysRole.setMenuIds(menuRole);
        sysRole.setStatus("0");
        sysRole.setRoleSort("1");
        sysRole.setRoleKey(user.getLoginName());
        sysRole.setRoleName(user.getPhonenumber());
        roleService.insertRole(sysRole);
        //添加用户角色关联
        Long[] roleIds = new Long[1];
        roleIds[0] = roleId;
        user.setRoleIds(roleIds);
        user.setFunctionMenu("");*/
        return toAjax(userService.insertUser(user));
    }

    /**
     * 修改用户
     */
    @GetMapping("/edit/{userId}")
    public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        SysUser sysUser = userService.selectUserById(userId);
        String[] homeMenus;
        String[] functionMenus;
        List<AppMenu> homeMenuList = new ArrayList<>();
        /*List<AppMenu> functionMenuList = new ArrayList<>();*/
        AppMenu appMenu = new AppMenu(IdWorker.getId(),"1","产品出库");
        AppMenu appMenu2 = new AppMenu(IdWorker.getId(),"2","领取配货单");
//        AppMenu appMenu3 = new AppMenu(IdWorker.getId(),"3","自主配货");
        AppMenu appMenu4 = new AppMenu(IdWorker.getId(),"4","待发货订单");
        AppMenu appMenu5 = new AppMenu(IdWorker.getId(),"5","待配货订单");
        AppMenu appMenu6 = new AppMenu(IdWorker.getId(),"6","待验货订单");
        AppMenu appMenu7 = new AppMenu(IdWorker.getId(),"7","配货中订单");
        AppMenu appMenu8 = new AppMenu(IdWorker.getId(),"8","已发货订单");
        AppMenu appMenu9 = new AppMenu(IdWorker.getId(),"9","客户管理");
        AppMenu appMenu10 = new AppMenu(IdWorker.getId(),"10","客户退货");
        AppMenu appMenu11 = new AppMenu(IdWorker.getId(),"11","待审核订单");
        AppMenu appMenu12 = new AppMenu(IdWorker.getId(),"12","产品入库");
        AppMenu appMenu13 = new AppMenu(IdWorker.getId(),"13","供应商管理");
        AppMenu appMenu14 = new AppMenu(IdWorker.getId(),"14","退回厂家");
        AppMenu appMenu15 = new AppMenu(IdWorker.getId(),"15","产品库位变动");
        AppMenu appMenu16 = new AppMenu(IdWorker.getId(),"16","小程序预订单");
        AppMenu appMenu17 = new AppMenu(IdWorker.getId(),"17","入库单审核");
        AppMenu appMenu18 = new AppMenu(IdWorker.getId(),"18","客户退货单审核");
        AppMenu appMenu19 = new AppMenu(IdWorker.getId(),"19","返回厂家单审核");
        AppMenu appMenu20 = new AppMenu(IdWorker.getId(),"20","新增产品");
        AppMenu appMenu21 = new AppMenu(IdWorker.getId(),"21","挂起订单");
        AppMenu appMenu22 = new AppMenu(IdWorker.getId(),"22","订单结算");
        AppMenu appMenu23 = new AppMenu(IdWorker.getId(),"23","特价产品");
        AppMenu appMenu24 = new AppMenu(IdWorker.getId(),"24","统计");
        AppMenu appMenu25 = new AppMenu(IdWorker.getId(),"25","物流代收结算");
        AppMenu appMenu26 = new AppMenu(IdWorker.getId(),"26","结算记录");
        AppMenu appMenu27 = new AppMenu(IdWorker.getId(),"27","日常费用");
        AppMenu appMenu28 = new AppMenu(IdWorker.getId(),"28","待入库订单");
        AppMenu appMenu29 = new AppMenu(IdWorker.getId(),"29","调货清单");
        AppMenu appMenu30 = new AppMenu(IdWorker.getId(),"30","待入库调货单");
        AppMenu appMenu31 = new AppMenu(IdWorker.getId(),"31","缺货提醒");
        AppMenu appMenu33 = new AppMenu(IdWorker.getId(),"33","账务管理");
        AppMenu appMenu34 = new AppMenu(IdWorker.getId(),"34","利润管理");
        /*AppMenu appFMenu = new AppMenu(IdWorker.getId(),"1","待配货订单");
        AppMenu appFMenu2 = new AppMenu(IdWorker.getId(),"2","已配货订单");
        AppMenu appFMenu3 = new AppMenu(IdWorker.getId(),"3","配货中订单");
        AppMenu appFMenu4 = new AppMenu(IdWorker.getId(),"4","已发货订单");
        AppMenu appFMenu5 = new AppMenu(IdWorker.getId(),"5","客户管理");
        AppMenu appFMenu6 = new AppMenu(IdWorker.getId(),"6","退货管理");
        AppMenu appFMenu7 = new AppMenu(IdWorker.getId(),"7","待审核订单");*/
        homeMenuList.add(appMenu);
        homeMenuList.add(appMenu16);
//        homeMenuList.add(appMenu3);
        homeMenuList.add(appMenu5);
        homeMenuList.add(appMenu2);
        homeMenuList.add(appMenu7);
        homeMenuList.add(appMenu6);
        homeMenuList.add(appMenu11);
        homeMenuList.add(appMenu4);
        homeMenuList.add(appMenu8);
        homeMenuList.add(appMenu12);
        homeMenuList.add(appMenu17);
        homeMenuList.add(appMenu10);
        homeMenuList.add(appMenu18);
        homeMenuList.add(appMenu14);
        homeMenuList.add(appMenu19);
        homeMenuList.add(appMenu9);
        homeMenuList.add(appMenu13);
        homeMenuList.add(appMenu15);
        homeMenuList.add(appMenu20);
        homeMenuList.add(appMenu21);
        homeMenuList.add(appMenu22);
        homeMenuList.add(appMenu23);
        homeMenuList.add(appMenu24);
        homeMenuList.add(appMenu25);
        homeMenuList.add(appMenu26);
        homeMenuList.add(appMenu27);
        homeMenuList.add(appMenu28);
        homeMenuList.add(appMenu29);
        homeMenuList.add(appMenu30);
        homeMenuList.add(appMenu31);
        homeMenuList.add(appMenu33);
        homeMenuList.add(appMenu34);
        /*functionMenuList.add(appFMenu);
        functionMenuList.add(appFMenu2);
        functionMenuList.add(appFMenu3);
        functionMenuList.add(appFMenu4);
        functionMenuList.add(appFMenu5);
        functionMenuList.add(appFMenu6);
        functionMenuList.add(appFMenu7);*/
        if(EmptyUtils.isNotEmpty(sysUser.getHomeMenu())){
             homeMenus = sysUser.getHomeMenu().split(",");
            for (AppMenu temp : homeMenuList)
            {
                for (int i=0;i<homeMenus.length;i++)
                {
                    if (homeMenus[i].equals(temp.getAppMenuId()))
                    {
                        temp.setFlag(true);
                        break;
                    }
                }
            }
        }
        /*if(EmptyUtils.isNotEmpty(sysUser.getFunctionMenu())){
            functionMenus = sysUser.getFunctionMenu().split(",");
            for (AppMenu temp1 : functionMenuList)
            {
                for (int j=0;j<functionMenus.length;j++)
                {
                    if (functionMenus[j].equals(temp1.getAppMenuId()))
                    {
                        temp1.setFlag(true);
                        break;
                    }
                }
            }
        }*/
        mmap.put("user", userService.selectUserById(userId));
        mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        mmap.put("posts", postService.selectPostsByUserId(userId));
        mmap.put("homes", homeMenuList);
        /*mmap.put("functions", functionMenuList);*/
        return prefix + "/edit";
    }

    /**
     * 修改保存用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/getUser/{userId}")
    @ResponseBody
    public AjaxResult getUser(@PathVariable("userId") Long userId)
    {
        if(EmptyUtils.isNotEmpty(userId)){
            return new AjaxResult(AjaxResult.Type.SUCCESS,"success",userService.selectUserById(userId));
        }else{
            return  error();
        }
    }

    /**
     * 修改保存用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(@Validated SysUser user)
    {
        userService.checkUserAllowed(user);
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        /*SysUser sysUser = new SysUser();
        sysUser.setUserId(user.getUserId());
        sysUser.setPhonenumber(user.getPhonenumber());
        sysUser.setLoginName(user.getLoginName());
        sysUser.setPostIds(user.getPostIds());*/
        user.setUpdateBy(ShiroUtils.getLoginName());
        return toAjax(userService.updateUser(user));
    }

    /**
     * 修改保存用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/updateFunction")
    @ResponseBody
    public AjaxResult updateFunction(@Validated SysUser user)
    {
        String[] functionMenus = user.getFunctionMenu().split(",");
        Long[] menuRole =(Long[]) ConvertUtils.convert(functionMenus,Long.class);
        SysRole sysRole = roleService.selectRoleById(user.getRoleId());
        if(EmptyUtils.isNotEmpty(sysRole)){
            sysRole.setRoleId(user.getRoleId());
            sysRole.setMenuIds(menuRole);
            roleService.updateRole(sysRole);
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserId(user.getUserId());
        sysUser.setHomeMenu(user.getHomeMenu());
        return toAjax(userService.updateUserFunction(sysUser));
    }

    @RequiresPermissions("system:user:resetPwd")
    @GetMapping("/resetPwd/{userId}")
    public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        mmap.put("user", userService.selectUserById(userId));
        return prefix + "/resetPwd";
    }

    @RequiresPermissions("system:user:resetPwd")
    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    @ResponseBody
    public AjaxResult resetPwdSave(SysUser user)
    {
        userService.checkUserAllowed(user);
        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
        if (userService.resetUserPwd(user) > 0)
        {
            if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
            {
                ShiroUtils.setSysUser(userService.selectUserById(user.getUserId()));
            }
            return success();
        }
        return error();
    }

    /**
     * 进入授权角色页
     */
    @GetMapping("/authRole/{userId}")
    public String authRole(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        SysUser user = userService.selectUserById(userId);
        // 获取用户所属的角色列表
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        mmap.put("user", user);
        mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return prefix + "/authRole";
    }

    /**
     * 用户授权角色
     */
    @RequiresPermissions("system:user:add")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PostMapping("/authRole/insertAuthRole")
    @ResponseBody
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
    {
        userService.insertUserAuth(userId, roleIds);
        return success();
    }

    @RequiresPermissions("system:user:remove")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(userService.deleteUserById(Long.parseLong(ids)));
    }

    /**
     * 校验用户名
     */
    @PostMapping("/checkLoginNameUnique")
    @ResponseBody
    public String checkLoginNameUnique(SysUser user)
    {
        return userService.checkLoginNameUnique(user.getLoginName());
    }

    /**
     * 校验手机号码
     */
    @PostMapping("/checkPhoneUnique")
    @ResponseBody
    public String checkPhoneUnique(SysUser user)
    {
        return userService.checkPhoneUnique(user);
    }

    /**
     * 校验email邮箱
     */
    @PostMapping("/checkEmailUnique")
    @ResponseBody
    public String checkEmailUnique(SysUser user)
    {
        return userService.checkEmailUnique(user);
    }

    /**
     * 用户状态修改
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @RequiresPermissions("system:user:edit")
    @PostMapping("/changeStatus")
    @ResponseBody
    public AjaxResult changeStatus(SysUser user)
    {
        userService.checkUserAllowed(user);
        return toAjax(userService.changeStatus(user));
    }

    /**
     * 加载部门列表树
     */
    @RequiresPermissions("system:user:list")
    @GetMapping("/deptTreeData")
    @ResponseBody
    public List<Ztree> deptTreeData()
    {
        List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
        return ztrees;
    }

    /**
     * 选择部门树
     *
     * @param deptId 部门ID
     */
    @RequiresPermissions("system:user:list")
    @GetMapping("/selectDeptTree/{deptId}")
    public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
    {
        mmap.put("dept", deptService.selectDeptById(deptId));
        return prefix + "/deptTree";
    }
}